package cn.edu.nju.ws.sview.views;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;

import cn.edu.nju.ws.sview.cache.GroupCache;
import cn.edu.nju.ws.sview.cache.UserNameIDCache;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;
import cn.edu.nju.ws.sview.mail.*;
/**
 * personal profile setting 
 * personality setting such as favor and trush
 * @author gongsaisai
 *@author dhuang
 */
public class User_validate {
	
	public static final int SUNDAY = 0;
	public static final int MONDAY = 1;
	public static final int TUESDAY = 2;
	public static final int WEDNESDAY = 3;
	public static final int THURSDAY = 4;
	public static final int FRIDAY = 5;
	public static final int STAURDAY = 6;
	
	private String name;
	private String password;
	private String email;
	private String displayLanguage;
	private HashSet<String> languages;
	private HashSet<Integer> groups;
	
	public static String USER_VALIDATE = "clear_validate_user";
	
	public String getName(Integer userID) throws Throwable {
			try {
				Connection conn = DBConnectionFactory.getConnection();
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery(String.format(
						"select name from user_validate where id=%d", userID));
				if ( rs.next() ) {
					name = rs.getString("name");
				}
				rs.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		return name;
	}
	
	public int getUserID() throws Throwable {
        if(name==null)
        	return -1;
		Integer userID =-1;
			try {
				Connection conn = DBConnectionFactory.getConnection();
				Statement stmt = conn.createStatement();
				ResultSet rs = stmt.executeQuery(String.format(
						"select id from user_validate where name = '%s'", name));
				if ( rs.next() ) {
					userID= rs.getInt("id");
				}
				rs.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		if(userID==null)
			return -1;
		else
			return userID;
	}
	
	
	public User_validate(String name) {
		this.name = name;
	}
	
	/*public static int getUserIdByName(String name) {
		int id = -1;
		if(name==null)
			return id;
		try {
			int mid =  UserNameIDCache.getInstance().getUserID(name) ;
			if(mid>0)
				id = mid;
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return id;
	}
	
	public static String getUserNameById(int id){
		String name = null;
	     try {
			name = UserNameIDCache.getInstance().getName(id) ;
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return name;
	}*/
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setPassword(String password) {
		this.password = password;
	}
	
	public void setDisplayLang(String lang) {
		this.displayLanguage = lang;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}
	
	public void setLanguages(HashSet<String> languages) {
		this.languages = languages;
	}
	
	public void setPreferedLangsInDB(HashSet<String> languages) throws Throwable{
		setLanguages(languages);
		this.serializePreferredLanguages();
	}
	
	public void serializeDisplayLanguage() {
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			stmt.executeUpdate(String.format(
					"update user_validate " +
					"set lang = '%s' " +
					"where name = '%s'",
					displayLanguage, name));
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * store the prefered languages. The function can be used to update preferred langs
	 * must set the preferred language in user object first
	 * @throws Throwable 
	 */
	public void serializePreferredLanguages() throws Throwable {
		int uid = getUserID();
		if ( uid < 0 ) return;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			stmt.executeUpdate(String.format(
					"delete from user_validate_prefer " +
					"where user_id = %d", uid));
			stmt.close();
			
			PreparedStatement pstmt = conn.prepareStatement(
					"insert into user_validate_prefer(user_id, lang) " +
					"values(?, ?)");
			pstmt.setInt(1, uid);
			for (String language : languages) {
				pstmt.setString(2, language);
				pstmt.executeUpdate();
			}
			pstmt.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * update the password and email
	 * must be update the memory user object's email and password first
	 */
	public void serializePasswordEmail() {
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			stmt.executeUpdate(String.format(
					"update user_validate " +
					"set password = '%s', email = '%s' " +
					"where name = '%s'",
					password, email, name));
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * create a new user, if exist return false
	 * @return false if exist
	 * @throws Throwable 
	 */
	public boolean serialize(String code) throws Throwable {
		int uid = getUserID();
		if ( uid > 0 ) return false;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			PreparedStatement stmt = conn.prepareStatement("insert into user_validate(name, password, email,code,create_time)"
															+ "values(?,?,?,?,?)") ;
			stmt.setString(1, name) ;
			stmt.setString(2, password) ;
			stmt.setString(3, email) ;
			stmt.setString(4, code) ;
			Calendar d=Calendar.getInstance();
			int day_of_week = d.get(Calendar.DAY_OF_WEEK)-1;
			stmt.setInt(5, day_of_week) ;
			stmt.executeUpdate();
			stmt.close();
			conn.close();
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public void setGroups(){
		try {
			this.groups.add(0);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public String getName() {
		return name;
	}
	
	public static String getNameByCode(String code) {
		if ( code == null ) return null;
		String tmp_name = null;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select name " +
					"from user_validate " +
					"where code = '%s'",
					code));
			if ( rs.next() ) {
				tmp_name = rs.getString("name");
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return tmp_name;
	}
	
	/**
	 * 获得默认的编辑组
	 */
	public  static int getDefaultGroup(int userID){
		int result = 0;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rsResultSet = stmt.executeQuery(String.format(
					"select default_group_id from user_validate where id=%d" 
					, userID));
			
			if(rsResultSet.next()){
				result = rsResultSet.getInt("default_group_id");
			}
			rsResultSet.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * get the password from the database
	 * @return
	 */
	public String getPassword() {
		if ( password != null ) return password;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select password " +
					"from user_validate " +
					"where name = '%s'",
					name));
			if ( rs.next() ) {
				password = rs.getString("password");
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return password;
	}
	
	/**
	 * get the email from the database
	 * @return
	 */
	public String getEmail() {
		if ( email != null ) return email;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select email " +
					"from user_validate " +
					"where name = '%s'",
					name));
			if ( rs.next() ) {
				email = rs.getString("email");
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return email;
	}
	
	/**
	 * get the preferred language form the database
	 * @return empty if the user not exist 
	 * @throws Throwable 
	 */
	public HashSet<String> getPreferedLanguages() throws Throwable {
		if ( languages != null ) return languages;
		int uid = getUserID();
		if ( uid <= 0 ) return  new HashSet<String>();
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select lang from user_validate_prefer " +
					"where user_id = '%d'", uid));
			languages = new HashSet<String>();
			while ( rs.next() ) {
				languages.add(rs.getString("lang"));
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return languages;
	}
	
	/**
	 * get the display language from the database
	 * @return
	 */
	public String getDisplayLanguage() {
		if ( displayLanguage != null ) return displayLanguage;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select lang from user_validate " +
					"where name = '%s'", name));
			if ( rs.next() ) {
				displayLanguage = rs.getString("lang");
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return displayLanguage;
	}
	
	public HashSet<Integer> getGroups(){
		if(this.groups == null){
			this.setGroups();
		}
		return this.groups;
	}
	public void updateGroups(){
		try {
			this.groups = GroupCache.getInstance().updateGroupIDs(getUserID());
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	@Override
	public int hashCode() {
		return name.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		return name.equals(((User_validate) obj).name);
	}
	
	public static void deleteUser(String name) throws Throwable{
		User_validate validate=new User_validate(name);
		Integer id= validate.getUserID();
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			stmt.executeUpdate(String.format(
					"delete from user_validate " +
					"where name = '%s'", name));
			stmt.executeUpdate(String.format(
					"delete from user_validate_prefer " +
					"where user_id = '%s'", id));
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}


